package com.itheima.health.security;

import com.alibaba.fastjson.JSON;
import com.itheima.health.entity.Result;
import com.itheima.health.pojo.Permission;
import com.itheima.health.pojo.Role;
import com.itheima.health.pojo.User;
import com.qiniu.util.Json;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.AntPathMatcher;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * @author ：石破天
 * @date ：Created in 2022/6/3
 * @description ：
 * @version: 1.0
 */
@Slf4j
@SuppressWarnings("all")
@WebFilter(urlPatterns = "/*")
public class HealthSecurityFilter implements Filter {
    //设置一个白名单不需要登录的uri
    String[] auths = new String[]{
            "/user/login",
            "/user/logout",
            "/common/**",
            "/mobile/**" //移动端
    };


    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        //定义一个权限路径与关键字的映射集合放在初始化中初始化
        initAutlUrlMap();

    }


    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse,
                         FilterChain filterChain) throws IOException, ServletException {
        //拦截所有请求
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        // 1.获取URI
        String uri = request.getRequestURI();
        log.info("[权限检查过滤器...],当前uri:{}", uri);
        //判断是否为白名单
        if (checkwhitelist(uri)) {
            filterChain.doFilter(request, response);
            return;
        }
        //判断是否登录了
        Object user = request.getSession().getAttribute("user");
        //没有登录就响应一个jason信息
        if (user != null) {
            //登录成功就验证权限
            //有权限就放行
            if (checkpermuri(uri, (User) user)) {
                filterChain.doFilter(request, response);
            } else {
                response.setContentType("application/json;charset=utf-8");
                Result result = new Result(false, "对不起您没有权限");
                String string = JSON.toJSONString(result);
                response.getWriter().write(string);
            }
        } else {


            //设置Jason解析格式
            response.setContentType("application/json;charset=utf-8");
            Result result = new Result(false, "登陆失败，重新登录");
            String string = JSON.toJSONString(result);
            response.getWriter().write(string);


        }
    }

        @Override
        public void destroy () {

        }

        //登录之前需要的判断
        private boolean checkwhitelist (String requesturi){
            //路径匹配器
            AntPathMatcher antPathMatcher = new AntPathMatcher();
            //遍历白名单与之对比
            for (String auth : auths) {
                //条件判断为真就是白名单
                if (antPathMatcher.match(auth, requesturi)) {
                    return true;
                }
            }
            //否则就不是白名单需要登陆
            return false;
        }

        //登录之后判断用户是否拥有该访问的授权
        private boolean checkpermuri (String requesturi, User user){
            AntPathMatcher antPathMatcher = new AntPathMatcher();
            //先要判断是否是需要授权的也就是拿map映射的建和路径匹配
            Set<String> keySet = loginAuthUrlMap.keySet();
            //如果匹配上就需要获取该key对应的值也就是权限的关键字
            String keywords = null;

            for (String uri : keySet) {
                //匹配上就需要权限验证
                if (antPathMatcher.match(uri, requesturi)) {
                    keywords = uri;

                }
            }
            //没有就说明该请求都可以访问
            if (keywords == null) {

                return true;
            }
            //否则就是需要权限访问根据key获取关键字就行匹配
            String valuewords = loginAuthUrlMap.get(keywords);
            //遍历用户查看用户是否具有这个权限也就是关键字
            Set<Role> roles = user.getRoles();
            for (Role role : roles) {
                Set<Permission> permissions = role.getPermissions();
                for (Permission permission : permissions) {
                    //用户的权限所有关键字
                    String keyword = permission.getKeyword();
                    if (keyword.equals(valuewords)) {
                        //当前路径需要的权限和用户拥有的权限对应上允许访问
                        return true;
                    }
                }
            }
            //没对应上就不可以访问
            return false;

        }

        private Map<String, String> loginAuthUrlMap = new HashMap<>();

        private void initAutlUrlMap () {
            //路径和权限关键字map映射
            loginAuthUrlMap.put("/checkitem/delete", "CHECKITEM_DELETE");
            loginAuthUrlMap.put("/checkitem/add", "SETMEAL_ADD");
            loginAuthUrlMap.put("/checkitem/findById", "SETMEAL_QUERY");
            loginAuthUrlMap.put("/checkitem//edit", "CHECKITEM_EDIT");
            loginAuthUrlMap.put("/checkgroup/delete", "CHECKGROUP_DELETE");
            loginAuthUrlMap.put("/checkgroup/add", "CHECKGROUP_ADD");
            loginAuthUrlMap.put("/checkgroup/edit", "CHECKITEM_EDIT");
            loginAuthUrlMap.put("/checkgroup/findById", "CHECKITEM_QUERY");
            loginAuthUrlMap.put("/setmeal/delete", "SETMEAL_DELETE");
            loginAuthUrlMap.put("/report/**", "REPORT_VIEW");
            loginAuthUrlMap.put("/ordersetting", "ORDERSETTING");


        }

    }